home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / cli / okami15.lzh / OKAMI15 / SOURCE / FORMAT.C next >
Text File  |  1992-09-20  |  7KB  |  279 lines

  1. /**********************************************************************
  2.  
  3.     Programm zum Formatieren von Disketten
  4.  
  5.  
  6.         von Wolfram Rösler
  7.              
  8.  
  9.       zum Aufruf als TTP oder von der Okami-Shell
  10.  
  11.  
  12. Datum      Ver.    Änderung
  13. 20.10.90  1.1    Volume Label (-l)
  14. 14.01.91  1.2    Schwerer Fehler beseitigt: &argv[i][2] statt argv[i][2]
  15. 24.05.91  1.3    Fehlerabfragen; -V: Versionsnummer
  16. 25.07.91  1.4    MSDOS-kompatibler Bootsektor
  17. 01.12.91  1.5    Anpassung an TurboC/PureC (Ansi-C)
  18. 06.04.92  1.6    Flag -R: Seriennummer ändern
  19.  
  20. **********************************************************************/
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #include <tos.h>
  26.  
  27. #define PRGNAME     "format"    /* eigentlich: argv[0]            */
  28. #define VERSION        "1.6"    /* Versionsnummer            */
  29. #define FLAG_NOBOOT (-99)    /* Flag für keinen Bootsektor anlegen    */
  30. #define FLAG_NOFMT  (-987)    /* Flag für nur Bootsektor anlegen    */
  31. #define FLAG_NEWSNR (-9876)    /* Flag für nur Versionsnummer ändern    */
  32. #define MAGIC        0x87654321L /* Magische Zahl, hexhexhex        */
  33. #define SECSIZE     512     /* Bytes pro Sektor            */
  34. #define FMTBUFSIZE  0x3000    /* Formatierpuffer            */
  35.  
  36. /* VT52-Steuercodes */
  37. #define C_SAVE        "\033j"
  38. #define C_RESTORE    "\033k"
  39.  
  40. char TError[]="!!! Error";
  41.  
  42. int YesOrNo(void)
  43. {
  44.   fputs("Do you really want to do that? (y or n) ",stdout);
  45.   fflush(stdout);
  46.   return tolower(getchar())!='y';
  47. }
  48.  
  49.  
  50. int Format(int devno,int spt,int Sides,int Tracks,int interlv,
  51.     unsigned virgin,long SerNo,int Exec,int Quiet,char *VolLbl)
  52. {
  53.   register int i,j;
  54.   register char *Buf;
  55.   int Erg;
  56.  
  57.   if (Exec==FLAG_NEWSNR)
  58.   {
  59.     char B[1024];
  60.     if (Floprd(B,0L,devno,1,0,0,1)!=0)
  61.     {
  62.       perror("Error reading bootsector");
  63.       return errno;
  64.     }
  65.     Protobt(B,SerNo,-1,-1);
  66.     if (Flopwr(B,0L,devno,1,0,0,1)!=0)
  67.     {
  68.       perror("Error writing bootsector");
  69.       return errno;
  70.     }
  71.     return 0;
  72.   }
  73.   
  74.   if (Exec!=FLAG_NOFMT)
  75.   {
  76.   
  77.     if (!Quiet)
  78.     {
  79.   
  80.       /* Parameter checken */
  81.       if (devno!=0 && devno!=1)
  82.       {   
  83.     printf("You are about to format drive %c.\n",(char)devno+'A');    
  84.     if (YesOrNo())
  85.       return 0;
  86.       }
  87.     
  88.       if (virgin!=0xe5e5)
  89.       {
  90.     printf("You are about to format with a virgin of 0x%x.\n",virgin);
  91.     if (YesOrNo())
  92.       return 0;
  93.       }
  94.     
  95.       /* Letzte Warnung */
  96.       printf(
  97.       "LAST CHANCE TO STOP:\nYou are about to format the disk in drive %c.\n",
  98.       (char)devno+'A');
  99.     
  100.       if (YesOrNo())
  101.         return 0;
  102.     
  103.     } /* if (!Quiet) */
  104.       
  105.     /* Los gehts */
  106.     
  107.     /* Speicher für Rückgabewert */
  108.     Buf=calloc(FMTBUFSIZE,sizeof(int));
  109.     if (Buf==NULL)
  110.     {
  111.       fprintf(stderr,"%s: Out of memory (need %d bytes)\n",PRGNAME,
  112.                         FMTBUFSIZE*sizeof(int));
  113.       return 1;
  114.     }
  115.     
  116.     /* *** FORMATIEREN *** */
  117.     
  118.     printf("Formatting disk %c, %d side%s, %d tracks, %d sec/track\n%s",
  119.         (char)devno+'A',Sides,Sides==1?"":"s",Tracks,spt,C_SAVE);
  120.  
  121.     for (i=Tracks-1;i>=0;i--)
  122.       for (j=0;j<Sides;j++)
  123.       {
  124.     printf("%s%sSide %d Track %d  ",C_RESTORE,C_SAVE,j,i);
  125.     fflush(stdout);
  126.     Erg=Flopfmt((int *)Buf,0L,devno,spt,i,j,interlv,MAGIC,
  127.                             i>1 ? virgin : 0);
  128.     if (Erg!=0)
  129.     {
  130.       fprintf(stderr,"\n%s %d on side %d, track %d\n",TError,Erg,j,i);
  131.       free(Buf);
  132.       return 1;
  133.     }
  134.       }
  135.  
  136.     free(Buf);
  137.     fputs(C_RESTORE,stdout);
  138.  
  139.   } /* if (Formatieren) */ 
  140.  
  141.   /* *** BOOTSEKTOR *** */
  142.   
  143.   if (Exec!=FLAG_NOBOOT)
  144.   {
  145.     printf("Creating %sexecutable boot sector",Exec ? "" : "non-");
  146.     fflush(stdout);
  147.     Buf=malloc(SECSIZE);
  148.     if (Buf==0)
  149.     {
  150.       fprintf(stderr,"\n%s: Out of memory (need %d bytes)\n",PRGNAME,
  151.                                 SECSIZE);
  152.       return 1;
  153.     }
  154.     Protobt(Buf,SerNo,(Sides-1)+(((Tracks/40)-1)<<1),Exec);
  155.     /* MSDOS-kompatibel */
  156.     Buf[0]=0xeb;
  157.     Buf[1]=0x34;
  158.     Buf[2]=0x90;
  159.     Erg=Flopwr(Buf,0L,devno,1,0,0,1);
  160.     free(Buf);
  161.     if (Erg!=0)
  162.     {
  163.       fprintf(stderr,"\n%s %d writing bootsector\n",TError,Erg);
  164.       return 1;
  165.     }
  166.   }
  167.  
  168.   fputc('\n',stdout);
  169.  
  170.   /* Diskettenname erzeugen */
  171.   if (VolLbl!=NULL && *VolLbl!='\0')
  172.   {
  173.     int Fd;
  174.     char Path[80+1];
  175.  
  176.     printf("Creating volume label");
  177.     fflush(stdout);
  178.     sprintf(Path,"%c:\\%s",devno+'A',VolLbl);
  179.     Fd = (int)Fcreate(Path,1<<3);
  180.     if (Fd<0)
  181.       fprintf(stderr,"\n\t%s %d creating volume label\n",TError,Erg);
  182.     else
  183.       Fclose(Fd);
  184.     fputc('\n',stdout);
  185.   }
  186.   return 0;
  187. }
  188.  
  189. void Usage(char *PrgName)
  190. {
  191.   fprintf(stderr,
  192.    "Usage: %s [-V]|[-s(Sec/Trk)] [-t(Trk/Dsk)] [-1] [-i(interlv)] \\\n%s",PrgName,
  193.    "       [-v(virgin)] [-n(SerNo)] [-(N|B|R)] [-x] [-q] [-l(VolLbl)] [Drive]");
  194.   fprintf(stderr,"\nDefaults: -s9 -t80 -i1 -v0xE5E5 A:\n\n");
  195.   fprintf(stderr,"-1: Format Single Sided\n"
  196.          "-N: No Boot Sector\n"
  197.          "-B: Boot Sector only\n"
  198.          "-R: change ser# only\n"
  199.          "-x: Executable Boot Sector\n"
  200.          "-q: No security requests\n"
  201.          "-l: Volume Label (default: none)\n"
  202.          "-V: just print version number\n"
  203.          "Drive: A or B (floppy disk drives only, no hard disks!)\n");
  204. }
  205.  
  206. int main(int argc,char *argv[])
  207. {
  208.   int    devno    = 0;        /* Laufwerksnummer: 0 A:, 1 B:        */
  209.   int    spt    = 9;        /* Sektoren pro Track            */
  210.   int    Sides    = 2;        /* Anzahl Seiten (1/2)            */
  211.   int    Tracks    = 80;         /* Anzahl Tracks            */
  212.   int    interlv    = 1;        /* Interleave-Faktor            */
  213.   unsigned virgin = 0xe5e5;    /* Virgin-Wort für Sektoren        */
  214.   long    SerNo    = 0x01000001L;    /* Seriennummer für Bootsektor        */
  215.   int    Exec    = 0;        /* Bootsektor ausführbar        */
  216.   int    Quiet    = 0;        /* Flag Sicherheitsabfragen: 0 ja,1 nein*/
  217.   char *VolLbl    = NULL;        /* Diskettenname oder NULL        */
  218.   int i;
  219.   
  220.   if (argc==1)
  221.     return Format(devno,spt,Sides,Tracks,interlv,virgin,SerNo,Exec,Quiet,VolLbl);
  222.   
  223.   /* Parameter scannen */
  224.   for (i=1;i<argc;i++)
  225.   {
  226.     if (argv[i][0]=='-')        /* Flag */
  227.       switch(argv[i][1])
  228.       {
  229.         case 'V':            /* Versionsnummer    */
  230.       puts("Okami Format " VERSION);
  231.       puts("compiled " __DATE__ " " __TIME__);
  232.       exit(0);
  233.     case 's':            /* Sektoren pro Track    */
  234.       spt=atoi(&argv[i][2]);
  235.       break;
  236.     case 't':            /* Tracks pro Disk    */
  237.       Tracks=atoi(&argv[i][2]); 
  238.       break;
  239.     case '1':            /* Einseitig        */
  240.       Sides=1;
  241.       break;
  242.     case 'i':            /* Interleaf-Faktor    */
  243.       interlv=atoi(&argv[i][2]);
  244.       break;
  245.     case 'v':            /* Virgin-Wort        */
  246.       virgin=(unsigned)atoi(&argv[i][2]);
  247.       break;
  248.     case 'n':            /* Seriennummer     */
  249.       SerNo=atol(&argv[i][2]);
  250.       break;
  251.     case 'N':            /* kein Bootsektor    */
  252.       Exec=FLAG_NOBOOT;
  253.       break;
  254.     case 'B':            /* nur Bootsektor    */
  255.       Exec=FLAG_NOFMT;
  256.       break;
  257.     case 'R':            /* nur neue Seriennummer */
  258.       Exec=FLAG_NEWSNR;
  259.       break;
  260.     case 'x':            /* Bootsektor ausführbar*/
  261.       Exec=1;
  262.       break;
  263.     case 'q':            /* keine Sicherheitsabfragen */
  264.       Quiet=1;
  265.       break;
  266.     case 'l':            /* Diskettenname    */
  267.       VolLbl= &(argv[i][2]);
  268.       break;
  269.     default:            /* Falsches Flag    */
  270.       Usage(PRGNAME);
  271.       return 1;
  272.       }
  273.     else                /* Laufwerksnummer    */
  274.       devno=tolower(argv[i][0])-'a';
  275.   }
  276.  
  277.   return Format(devno,spt,Sides,Tracks,interlv,virgin,SerNo,Exec,Quiet,VolLbl);
  278. }
  279. ə